/*=========================================================
* 文 件 名: flash_operate.c
* 版 权: 火星人厨具
* 功能描述: 用于读写flash 和 data flash
* 包含文件: "cms80fx61x.h"
*
* 修改日期 修改人 修改说明
* 2023-06-13 汤勇 完成基本功能
=========================================================*/
#include "cms80f761xx.h"
#include "flash_operate.h"

/*=========================================================
* 函 数 名: f_Iap_WriteOneByte(u32 u32Addr,u8 u8Data,u8 u8Area)
* 功能描述: 写单字节IAP操作
* 调用方法: f_Iap_WriteOneByte(addr,area ,*pdat)
* 输入变量: 0：表示擦除DATA FLAH中前512位,1：表示写入数据
* 返回值: 1 ====> 写入成功
		  0 ====> 写入失败
=========================================================*/
u8 f_Iap_WriteOneByte(u32 addr ,u8 area ,u8 dat)
{    	
	FLASH_Write(area,addr, dat);	
	
    if(FLASH_Read(area,addr) == dat)
    {
        return 1;	//写入准确
    }
    else
    {
        return 0;	//写入有误
    }
}
/*=========================================================
* 函 数 名: f_Iap_FlagWrite(u32 addr , u8 area ,u8 *pdat)
* 功能描述: 将需要存储的标志写入DATA FLASH
* 调用方法: f_Iap_FlagWrite(DATA_BUFF_ADDR,FLASH_DATA ,u8IapCheckNum)
* 输入变量: addr ====> 地址
			area ====> FLASH_DATA或者FLASH_CODE
			*pdat ====> 表示将要写入的数据
* 返回值: 1 ====> 写入成功
		  0 ====> 写入失败
=========================================================*/
u8 f_Iap_FlagWrite(u32 addr , u8 area ,u8 *pdat)
{
    u8 i , ok = 0;
	FLASH_UnLock();
    FLASH_Erase(area , addr); 
	for(i = 0;i < IAP_CHECK_LENGTH; i++)
	{
		ok = f_Iap_WriteOneByte(addr + i,area ,*(pdat + i));
		if(ok == 0)
			break;
	}
	FLASH_Lock();
	return ok;
}

/*=========================================================
* 函 数 名: f_Iap_FlagRead(u32 addr , u8 area ,u8 *pdat)
* 功能描述: 将需要存储的标志写入DATA FLASH
* 调用方法: f_Iap_FlagRead(DATA_BUFF_ADDR,FLASH_DATA ,u8IapCheckNum)
* 输入变量: addr ====> 地址
			area ====> FLASH_DATA或者FLASH_CODE
			*pdat ====> 表示将要对比的数据
* 返回值: 1 ====> 读出对比成功
		  0 ====> 读出对比失败
=========================================================*/
u8 f_Iap_FlagRead(u32 addr , u8 area ,u8 *pdat)
{
    u8 i , ok = 1;
	FLASH_UnLock();
	for(i = 0;i < IAP_CHECK_LENGTH; i++)
	{
		if(*(pdat + i) != FLASH_Read(area , addr + i))
		{
			ok = 0;
			break;
		}
	}
	FLASH_Lock();
	return ok;
}
/*=========================================================
* 函 数 名: f_Iap_FlagErase(u32 addr , u8 area)
* 功能描述: 标志擦除
* 调用方法: f_Iap_FlagErase(DATA_BUFF_ADDR,FLASH_DATA)
* 输入变量: addr ====> 地址
			area ====> FLASH_DATA或者FLASH_CODE
* 返回值: 无
=========================================================*/
void f_Iap_FlagErase(u32 addr , u8 area)
{
	FLASH_UnLock();
	FLASH_Erase(area , addr); 
	FLASH_Lock();
}

/*=========================================================
* 函 数 名: f_Iap_Remap()
* 功能描述: 将应用区擦除，并且将备份区的程序写入应用区
* 调用方法: f_Iap_Remap() 
* 输入变量: 无
* 返回值: 无
=========================================================*/
void f_Iap_Remap() 
{
	u16 i;
	f_Iap_Erase_All(APROM_AREA); 
	FLASH_UnLock();
	for(i = 0; i < APP_SIZE; i++) 
	{
		f_Iap_WriteOneByte(APP_START_ADDR + i , FLASH_CODE , FLASH_Read(FLASH_CODE,BUFF_START_ADDR + i)); // 将数据写入应用区
		WDT_ClearWDT(); 
	}
	FLASH_Lock();
}

/*=========================================================
* 函 数 名: f_Iap_Erase_All(u8 area)
* 功能描述: 将相关区域擦除
* 调用方法: f_Iap_Erase_All(x)
* 输入变量: area====> 区域，变量有APROM_AREA，DATA_AREA和
					APROM_BUFF_AREA
* 返回值: 无
=========================================================*/
void f_Iap_Erase_All(u8 area)
{
    u16 i;
	u16 k = 0;
	u32 begin_addr = 0;
	if(area == APROM_AREA) // APP应用区
	{
		k = (APP_SIZE / ONE_PAGE_SIZE);
		begin_addr = APP_START_ADDR;
		area = FLASH_CODE;
	}
	else if(area == APROM_BUFF_AREA) // APP备份区
	{
		k = (APP_BUFF_SIZE / ONE_PAGE_SIZE);
		begin_addr = BUFF_START_ADDR;
		area = FLASH_CODE;
	}
	else if(area == DATA_AREA)	// DATA区，也即是存入标志位的区域
	{
		k = (DATA_BUFF_SIZE / ONE_PAGE_SIZE);
		begin_addr = DATA_BUFF_ADDR;
		area = FLASH_DATA;
	}
	
	FLASH_UnLock();
    for(i = 0 ; i < k ; i++) 
    {
		FLASH_Erase(area , i*ONE_PAGE_SIZE+begin_addr); 
		WDT_ClearWDT(); 
    }
	FLASH_Lock();
}
/**** (c) 火星人厨具*************************** END OF FILE **/
